home *** CD-ROM | disk | FTP | other *** search
/ User's Choice Windows CD / User's Choice Windows CD (CMS Software)(1993).iso / utility1 / gs261src.zip / ZMISC2.C < prev    next >
C/C++ Source or Header  |  1993-05-13  |  12KB  |  419 lines

  1. /* Copyright (C) 1992, 1993 Aladdin Enterprises.  All rights reserved.
  2.  
  3. This file is part of Ghostscript.
  4.  
  5. Ghostscript is distributed in the hope that it will be useful, but
  6. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  7. to anyone for the consequences of using it or for whether it serves any
  8. particular purpose or works at all, unless he says so in writing.  Refer
  9. to the Ghostscript General Public License for full details.
  10.  
  11. Everyone is granted permission to copy, modify and redistribute
  12. Ghostscript, but only under the conditions described in the Ghostscript
  13. General Public License.  A copy of this license is supposed to have been
  14. given to you along with Ghostscript so you can know your rights and
  15. responsibilities.  It should be in a file named COPYING.  Among other
  16. things, the copyright notice and this notice must be preserved on all
  17. copies.  */
  18.  
  19. /* zmisc2.c */
  20. /* Miscellaneous Level 2 operators for Ghostscript */
  21. #include "memory_.h"
  22. #include "ghost.h"
  23. #include "errors.h"
  24. #include "oper.h"
  25. #include "gsfont.h"
  26. #include "dict.h"
  27. #include "dparam.h"
  28. #include "dstack.h"
  29. #include "estack.h"
  30. #include "ilevel.h"
  31. #include "iname.h"        /* for dict_find_name */
  32. #include "store.h"
  33.  
  34. /* The (global) font directory */
  35. extern gs_font_dir *ifont_dir;        /* in zfont.c */
  36.  
  37. /* Import the Level 2 definitions directory from iinit.c. */
  38. extern ref ref_level2dict;
  39. #define level2dict (&ref_level2dict)
  40.  
  41. /* Import the Level 1 'where' operator from zdict.c. */
  42. extern int zwhere(P1(os_ptr));
  43.  
  44. /* The system parameter password */
  45. #define max_password 64            /* must be at least 11 */
  46. typedef struct password_s {
  47.     uint size;
  48.     byte data[max_password];
  49. } password;
  50. private password SystemParamsPassword = { 0 };
  51.  
  52. /* Forward references */
  53. private int set_language_level(P1(int));
  54. private void names_to_stack(P3(os_ptr, const ref _ds * _ds *, int));
  55. private int dict_password_param(P3(const ref *, const ref *, password *));
  56.  
  57. /* Names used for the 'where' hack. */
  58. static ref name_setcolor;
  59. static ref name_FreeHandDict;
  60.  
  61. /* User parameter names. */
  62. static ref name_MaxFontItem;
  63. static ref name_MinFontCompress;
  64. static ref name_MaxOpStack;
  65. static ref name_MaxDictStack;
  66. static ref name_MaxExecStack;
  67. static ref name_MaxLocalVM;
  68.  
  69. /* System parameter names. */
  70. static ref name_Password;        /* (only in incoming dictionaries) */
  71. static ref name_SystemParamsPassword;
  72. static ref name_BuildTime;
  73. static ref name_ByteOrder;
  74. static ref name_RealFormat;
  75. static ref name_MaxFontCache;
  76. static ref name_CurFontCache;
  77.  
  78. /* Initialization */
  79. private void
  80. zmisc2_init(void)
  81. {
  82.     static const names_def uspn[] = {
  83.         /* needed for 'where' */
  84.        { "setcolor", &name_setcolor },
  85.        { "FreeHandDict", &name_FreeHandDict },
  86.         /* User parameters */
  87.        { "MaxFontItem", &name_MaxFontItem },
  88.        { "MinFontCompress", &name_MinFontCompress },
  89.        { "MaxOpStack", &name_MaxOpStack },
  90.        { "MaxDictStack", &name_MaxDictStack },
  91.        { "MaxExecStack", &name_MaxExecStack },
  92.        { "MaxLocalVM", &name_MaxLocalVM },
  93.         /* System parameters */
  94.        { "Password", &name_Password },
  95.        { "SystemParamsPassword", &name_SystemParamsPassword },
  96.        { "BuildTime", &name_BuildTime },
  97.        { "ByteOrder", &name_ByteOrder },
  98.        { "RealFormat", &name_RealFormat },
  99.        { "MaxFontCache", &name_MaxFontCache },
  100.        { "CurFontCache", &name_CurFontCache },
  101.        names_def_end
  102.     };
  103.     init_names(uspn);
  104. }
  105.  
  106. /* ------ Language level operators ------ */
  107.  
  108. /* - .languagelevel <1 or 2> */
  109. private int
  110. zlanguagelevel(register os_ptr op)
  111. {    push(1);
  112.     ref_assign(op, &ref_language_level);
  113.     return 0;
  114. }
  115.  
  116. /* <1 or 2> .setlanguagelevel - */
  117. private int
  118. zsetlanguagelevel(register os_ptr op)
  119. {    int code = 0;
  120.     check_type(*op, t_integer);
  121.     if ( op->value.intval < 1 || op->value.intval > 2 )
  122.         return_error(e_rangecheck);
  123.     if ( op->value.intval != ref_language_level.value.intval )
  124.     {    code = set_language_level((int)op->value.intval);
  125.         if ( code < 0 ) return code;
  126.     }
  127.     pop(1);
  128.     ref_assign_old(&ref_language_level, op, "setlanguagelevel");
  129.     return code;
  130. }
  131.  
  132. /* ------ User and system parameters ------ */
  133.  
  134. /* <dict> setsystemparams - */
  135. private int
  136. zsetsystemparams(register os_ptr op)
  137. {    int code;
  138.     int ival;
  139.     password pass;
  140.     check_read_type(*op, t_dictionary);
  141.     if ( SystemParamsPassword.size != 0 )
  142.     {    code = dict_password_param(op, &name_Password, &pass);
  143.         if ( code ) return (code < 0 ? code : e_invalidaccess);
  144.         if ( pass.size != SystemParamsPassword.size ||
  145.              bytes_compare(&pass.data[0], pass.size,
  146.                  &SystemParamsPassword.data[0],
  147.                  SystemParamsPassword.size) != 0
  148.            )
  149.             return_error(e_invalidaccess);
  150.     }
  151.     code = dict_password_param(op, &name_SystemParamsPassword, &pass);
  152.     if ( code <= 0 )
  153.     {    if ( code < 0 ) return code;
  154.         SystemParamsPassword = pass;
  155.     }
  156.     code = dict_int_param(op, &name_MaxFontCache, 0, max_int, 0, &ival);
  157.     switch ( code )
  158.     {
  159.     default:            /* invalid */
  160.         return code;
  161.     case 1:                /* missing */
  162.         break;
  163.     case 0:
  164.         /****** NOT IMPLEMENTED YET ******/
  165.         ;
  166.     }
  167.     pop(1);
  168.     return 0;
  169. }
  170.  
  171. /* - .currentsystemparams <name1> <value1> ... */
  172. private int
  173. zcurrentsystemparams(os_ptr op)
  174. {    register os_ptr rop = op;
  175. #if arch_floats_are_IEEE
  176.     static const char rfs[] = "IEEE";
  177. #else
  178.     static const char rfs[] = "not IEEE";
  179. #endif
  180.     static const ref _ds *spn[] = {
  181.         &name_ByteOrder, &name_RealFormat, &name_BuildTime,
  182.         &name_MaxFontCache, &name_CurFontCache
  183.     };
  184. #define num_sp countof(spn)
  185.     uint cstat[7];
  186.     push(num_sp * 2);
  187.     names_to_stack(rop, spn, num_sp);
  188.     rop += 2;
  189.     make_bool(rop, !arch_is_big_endian);
  190.     rop += 2;
  191.     make_const_string(rop, a_readonly, sizeof(rfs) - 1,
  192.               (const byte *)rfs);
  193.     rop += 2;
  194.     make_int(rop, 0);            /* BOGUS */
  195.     gs_cachestatus(ifont_dir, cstat);
  196.     rop += 2;
  197.     make_int(rop, cstat[1]);
  198.     rop += 2;
  199.     make_int(rop, cstat[0]);
  200. #undef num_sp
  201.     return 0;
  202. }
  203.  
  204. /* <dict> setuserparams - */
  205. private int
  206. zsetuserparams(register os_ptr op)
  207. {    int code;
  208.     int ival;
  209.     check_read_type(*op, t_dictionary);
  210.     code = dict_int_param(op, &name_MaxFontItem, 0, max_int, 0, &ival);
  211.     switch ( code )
  212.     {
  213.     default:            /* invalid */
  214.         return code;
  215.     case 1:                /* missing */
  216.         break;
  217.     case 0:
  218.         if ( (code = gs_setcacheupper(ifont_dir, ival)) < 0 )
  219.             return code;
  220.     }
  221.     code = dict_int_param(op, &name_MinFontCompress, 0, max_int, 0, &ival);
  222.     switch ( code )
  223.     {
  224.     default:            /* invalid */
  225.         return code;
  226.     case 1:                /* missing */
  227.         break;
  228.     case 0:
  229.         if ( (code = gs_setcachelower(ifont_dir, ival)) < 0 )
  230.             return code;
  231.     }
  232.     pop(1);
  233.     return 0;
  234. }
  235.  
  236. /* - .currentuserparams <name1> <value1> ... */
  237. private int
  238. zcurrentuserparams(os_ptr op)
  239. {    register os_ptr rop = op;
  240.     long cur_vm, max_vm;
  241.     static const ref _ds *upn[] = {
  242.         &name_MaxFontItem, &name_MinFontCompress,
  243.         &name_MaxOpStack, &name_MaxDictStack, &name_MaxExecStack,
  244.         &name_MaxLocalVM
  245.     };
  246. #define num_up countof(upn)
  247.     push(num_up * 2);
  248.     names_to_stack(rop, upn, num_up);
  249.     rop += 2;
  250.     make_int(rop, gs_currentcacheupper(ifont_dir));
  251.     rop += 2;
  252.     make_int(rop, gs_currentcachelower(ifont_dir));
  253.     rop += 2;
  254.     make_int(rop, ostop - osbot + 1);
  255.     rop += 2;
  256.     make_int(rop, dstop - dsbot + 1);
  257.     rop += 2;
  258.     make_int(rop, estop - esbot + 1);
  259.     alloc_status(&cur_vm, &max_vm);
  260.     rop += 2;
  261.     make_int(rop, max_vm);
  262.     return 0;
  263. }
  264.  
  265. /* ------ The 'where' hack ------ */
  266.  
  267. private int
  268. z2where(register os_ptr op)
  269. {    /*
  270.      * Aldus Freehand versions 2.x check for the presence of the
  271.      * setcolor operator, and if it is missing, substitute a procedure.
  272.      * Unfortunately, the procedure takes different parameters from
  273.      * the operator.  As a result, files produced by this application
  274.      * cause an error if the setcolor operator is actually defined.
  275.      * Aldus fixed this bug in Freehand 3.0, but there are a lot of
  276.      * files created by the older versions still floating around.
  277.      * Therefore, at Adobe's suggestion, we implement the following
  278.      * dreadful hack in the 'where' operator:
  279.      *    If the key is /setcolor,
  280.      *     there is a dictionary named FreeHandDict, and
  281.      *     currentdict is that dictionary,
  282.      *    then "where" consults only that dictionary and not any other
  283.      *     dictionaries on the dictionary stack.
  284.      */
  285.     const ref *pdref = dsp;
  286.     ref *pvalue;
  287.     if ( !obj_eq(op, &name_setcolor) ||
  288.          (pvalue = dict_find_name(&name_FreeHandDict)) == 0 ||
  289.          !obj_eq(pvalue, pdref)
  290.        )
  291.         return zwhere(op);
  292.     check_dict_read(*pdref);
  293.     if ( dict_find(pdref, op, &pvalue) > 0 )
  294.     {    ref_assign(op, pdref);
  295.         push(1);
  296.         make_true(op);
  297.     }
  298.     else
  299.         make_false(op);
  300.     return 0;
  301. }
  302.  
  303. /* ------ Initialization procedure ------ */
  304.  
  305. /* The level setting ops are recognized even in Level 1 mode. */
  306. op_def zmisc2_level_op_defs[] = {
  307.     {"0.languagelevel", zlanguagelevel},
  308.     {"1.setlanguagelevel", zsetlanguagelevel},
  309.     op_def_end(0)
  310. };
  311. op_def zmisc2_op_defs[] = {
  312.     {"0.currentsystemparams", zcurrentsystemparams},
  313.     {"0.currentuserparams", zcurrentuserparams},
  314.     {"1setsystemparams", zsetsystemparams},
  315.     {"1setuserparams", zsetuserparams},
  316. /* Note that this overrides the definition in zdict.c. */
  317.     {"1where", z2where},
  318.     op_def_end(zmisc2_init)
  319. };
  320.  
  321. /* ------ Internal procedures ------ */
  322.  
  323. /* Adjust the interpreter for a change in language level. */
  324. /* This is used for the setlanguage level operator, */
  325. /* and after a restore. */
  326. private int
  327. set_language_level(int level)
  328. {    if ( level == 2 )        /* from Level 1 to Level 2 */
  329.     {    /* Insert globaldict in the dictionary stack. */
  330.         /* memcpy isn't guaranteed to work top-to-bottom. */
  331.         ref ndict;
  332.         ref *pdict;
  333.         int code;
  334.         register ds_ptr dp = dsp;
  335.         if ( dsp == dstop )
  336.             return_error(e_dictstackoverflow);
  337.         code = name_ref((const byte *)"globaldict", 10, &ndict, -1);
  338.         if ( code < 0 ) return code;
  339.         code = dict_find(level2dict, &ndict, &pdict);
  340.         if ( code <= 0 )
  341.             return_error(e_undefined);
  342.         if ( !r_has_type(pdict, t_dictionary) )
  343.             return_error(e_typecheck);
  344.         while ( dp > dsbot ) dp[1] = *dp, dp--;
  345.         dsbot[1] = *pdict;
  346.         min_dstack_size++;
  347.         dsp++;
  348.         /* Set other flags for Level 2 operation. */
  349.         dict_auto_expand = 1;
  350.     }
  351.     else                /* from Level 1 to Level 1 */
  352.     {    /* Remove globaldict from the dictionary stack. */
  353.         memcpy((char *)(dsbot + 1), (const char *)(dsbot + 2),
  354.                (int)((char *)dsp - (char *)(dsbot + 1)));
  355.         min_dstack_size--;
  356.         dsp--;
  357.         /* Set other flags for Level 1 operation. */
  358.         dict_auto_expand = 0;
  359.     }
  360.     /* Swap the contents of level2dict and systemdict. */
  361.     {    int index = dict_first(level2dict);
  362.         ref elt[2];        /* key, value */
  363.         ref *pvalue;
  364.         ref old_value;
  365.         while ( (index = dict_next(level2dict, index, &elt[0])) >= 0 )
  366.         {    int found = dict_find(systemdict, &elt[0], &pvalue);
  367.             switch ( found )
  368.             {
  369.             default:        /* <0, error */
  370.                 return found;
  371.             case 0:            /* missing */
  372.                 make_null(&old_value);
  373.                 break;
  374.             case 1:            /* present */
  375.                 old_value = *pvalue;
  376.             }
  377.             if ( r_has_type(&elt[1], t_null) )
  378.                 dict_undef(systemdict, &elt[0]);
  379.             else
  380.                 dict_put(systemdict, &elt[0], &elt[1]);
  381.             dict_put(level2dict, &elt[0], &old_value);
  382.         }
  383.     }
  384.     return 0;
  385. }
  386.  
  387. /* Copy names to the stack. */
  388. private void
  389. names_to_stack(os_ptr rop, const ref _ds * _ds * pnames, int count)
  390. {    for ( ++rop; count; rop += 2, pnames++, count-- )
  391.         *rop = **pnames;
  392. }
  393.  
  394. /* Get a password from a dictionary. */
  395. /* Return 0 if present, 1 if absent, or an error code. */
  396. private int
  397. dict_password_param(const ref *pdict, const ref *pname, password *ppass)
  398. {    ref *rpass;
  399.     int code = dict_find(pdict, pname, &rpass);
  400.     if ( code < 0 ) return 1;
  401.     switch ( r_type(rpass) )
  402.     {
  403.     case t_integer:
  404.         obj_cvs(rpass, &ppass->data[0], max_password, &ppass->size);
  405.         break;
  406.     case t_string:
  407.     {    uint size = r_size(rpass);
  408.         check_read(*rpass);
  409.         if ( size > max_password )
  410.             return_error(e_limitcheck);
  411.         memcpy(&ppass->data[0], rpass->value.const_bytes, size);
  412.         ppass->size = size;
  413.     }    break;
  414.     default:
  415.         return_error(e_typecheck);
  416.     }
  417.     return 0;
  418. }
  419.